<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class AccessMiddleware
{
    //用户token身份验证 验证后把用户身份信息写入request 供其他模块调用
    public function handle($request, Closure $next)
    {
        try {
            //先对输入进行过滤 防止sql注入和js攻击
            $request_arr = $request->all();
            if ($request_arr) {
                foreach ($request_arr as $key => $val) {
                    if (is_string($val)) {
                        //是字符串的话进行注入过滤
                        $val = $this->inject_check($val);
                        $request[$key] = $val;
                    }
                }
            }

            //日志记录请求方法和请求的参数
            Log::info('[' . $request->method() . ']' . $request->url() . "\r\n" . print_r($request->all(), true));
            
            $token = $request->header('token');
            //验证tokne是否为空，为空则返回失败，前端转向登录页面
            if (empty($token)) {
                $list['code'] = 2;
                $list['message'] = HTTP_NOLOGIN_MESSAGE;
                return response()->json($list);
            }

            //过期的token全部删除
            DB::table('sys_token')->where('expired_time', "<", date("Y-m-d H:i:s"))->delete();

            //根据token查询数据表token信息
            $tokeninfo = DB::table('sys_token')->where('token', $token)->where('expired_time', ">=", date("Y-m-d H:i:s"))->select('id', 'user_id')->first();

            if (!$tokeninfo) {
                //token不存在或已过期
                $list['code'] = 2;
                $list['message'] = HTTP_NOLOGIN_MESSAGE;
                return response()->json($list);
            }

            //延长token过期时间,增加1个小时
            $cond = [];
            $cond["expired_time"] = date("Y-m-d H:i:s", strtotime("+1 hours"));
            DB::table('sys_token')->where('id', $tokeninfo->id)->update($cond);

            //存储用户信息
            $request->user_id = $tokeninfo->user_id;
            return $next($request);
        } catch (\Exception $e) {
            // 记录错误日志
            Log::error('token验证失败: ' . $e->getMessage());

            return response()->json([
                'code' => 2,
                'message' => 'token验证失败',
            ]);
        }
    }


    //对传入的变量进行处理，避免sql注入
    function inject_check($str)
    {
        $str = trim($str); //去除空格
        $str = str_replace(" or ", "", $str); // or过滤掉
        // 过滤掉<script>标签
        $str = preg_replace("/<script[\s\S]*?<\/script>/i", "", $str);
        $str = preg_replace("/\&lt\;script[\s\S]*?\&lt\;\/script\&gt\;/i", "", $str);
        $str = str_replace("%", "\%", $str); // 把' % '过滤掉
        return $str;
    }


}
